home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-05-05 | 30.2 KB | 1,345 lines | [TEXT/R*ch] |
- /* NAME:
- LPasswordField.cp
-
- WRITTEN BY:
- Dair Grant, dair@kagi.com, http://www.kagi.com/authors/dair
-
- DESCRIPTION:
- A Pane containing editable text, which only displays bullet characters.
-
- Use an LPasswordField for small amounts of monstyled text, such as a
- text entry field in a dialog box. PasswordField derives from the
- LEditField class, so similar restrictions apply to its usage (it uses
- TextEdit, and it's not a View, so you can't put a PasswordField in a
- Scroller).
-
- PasswordFields should behave *exactly* like EditFields, the only
- difference being that characters are always displayed as bullets.
- You use the same routines (SetDescriptor/GetDescriptor and SetValue/
- GetValue) to manipulate the text, and the same commands can be
- performed on it (cut, copy, paste, etc). The PasswordField takes
- care of ensuring that only bullets are ever displayed.
-
- The bullet character defaults to '•'. The SetBullet method allows
- this to be changed.
-
- To use a PasswordField, create and position an EditField with
- Constructor, and set the class ID to 'pass' once you're happy with
- it. Then include LPasswordField.h in the relevent source files,
- add LPasswordField.cp to your project, and put the line
-
- URegistrar::RegisterClass(LPasswordField::class_ID,
- LPasswordField::CreatePasswordFieldStream);
-
- in your application's constructor.
-
- You may use the LPasswordField class in any project you write,
- without restriction. Comments, bugs, or suggestions are more than
- welcome - send them to dair@kagi.com.
-
- ___________________________________________________________________________
- */
- //=============================================================================
- // Include files
- //-----------------------------------------------------------------------------
- #ifdef PowerPlant_PCH
- #include PowerPlant_PCH
- #endif
-
- #include <Scrap.h>
- #include <Script.h>
- #include <TextEdit.h>
- #include <ToolUtils.h>
-
- #include <LCommander.h>
- #include <LEditField.h>
- #include <LPane.h>
- #include <LPasswordField.h>
- #include <LStream.h>
- #include <PP_KeyCodes.h>
- #include <PP_Messages.h>
- #include <UDrawingState.h>
- #include <UKeyFilters.h>
- #include <UTETextAction.h>
- #include <UTextTraits.h>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // Private defines
- //-----------------------------------------------------------------------------
- #define kHiddenTEOffset 5000 // Offset for hidden TE record
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::CreatePasswordFieldStream
- //-----------------------------------------------------------------------------
- // Create a new PasswordField object from the data in a Stream.
- //-----------------------------------------------------------------------------
- LPasswordField *LPasswordField::CreatePasswordFieldStream(LStream *inStream)
- {
- return (new LPasswordField(inStream));
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::LPasswordField
- //-----------------------------------------------------------------------------
- // Default constructor.
- //-----------------------------------------------------------------------------
- LPasswordField::LPasswordField() : LEditField()
- {
- InitPassField(editAttr_Box);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::LPasswordField
- //-----------------------------------------------------------------------------
- // Copy constructor.
- //-----------------------------------------------------------------------------
- LPasswordField::LPasswordField(const LPasswordField &inOriginal) : LEditField(inOriginal)
- { Rect viewRect = {0, 0, 0, 0};
- Str255 theStr;
-
-
-
- // The LEditField constructor will have build our mTextEditH member.
- // We move it somewhere off screen so it won't be visible.
- ::OffsetRect(&(*mTextEditH)->viewRect, kHiddenTEOffset, kHiddenTEOffset);
-
-
- // Create the 'bullet' TextEdit record
- mBulletTextEditH = ::TENew(&viewRect, &viewRect);
-
-
- // Set our descriptor correctly and align everything correctly
- SetDescriptor(inOriginal.GetDescriptor(theStr));
- AlignTextEditRects();
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::LPasswordField
- //-----------------------------------------------------------------------------
- // Construct from input parameters.
- //-----------------------------------------------------------------------------
- LPasswordField::LPasswordField(const SPaneInfo &inPaneInfo,
- Str255 inString,
- ResIDT inTextTraitsID,
- Int16 inMaxChars,
- Boolean inHasBox,
- Boolean inHasWordWrap,
- KeyFilterFunc inKeyFilter,
- LCommander *inSuper) :
- LEditField(inPaneInfo, inString, inTextTraitsID, inMaxChars,
- inHasBox, inHasWordWrap, inKeyFilter, inSuper)
- { Uint8 attributes = 0;
-
-
-
- // Set our attributes, then initialise ourself with them
- if (inHasBox)
- attributes += editAttr_Box;
- if (inHasWordWrap)
- attributes += editAttr_WordWrap;
- InitPassField(attributes);
-
-
- // If we've been given a string, put it into the visible
- // TextEdit record and convert it to bullets
- if (inString[0] > 0)
- {
- ::TESetText(inString + 1, inString[0], mBulletTextEditH);
- SetTextToBullets(mBulletTextEditH);
- }
-
-
- // Align the TextEdit records and select the text, if any
- AlignTextEditRects();
- SelectAll();
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::LPasswordField
- //-----------------------------------------------------------------------------
- // Construct from input parameters.
- //-----------------------------------------------------------------------------
- LPasswordField::LPasswordField(const SPaneInfo &inPaneInfo,
- Str255 inString,
- ResIDT inTextTraitsID,
- Int16 inMaxChars,
- Uint8 inAttributes,
- KeyFilterFunc inKeyFilter,
- LCommander *inSuper) :
- LEditField(inPaneInfo, inString, inTextTraitsID, inMaxChars,
- inAttributes, inKeyFilter, inSuper)
- {
-
- // Initialise ourselves with the supplied attributes
- InitPassField(inAttributes);
-
-
- // If we've been given a string, put it into the visible
- // TextEdit record and convert it to bullets
- if (inString[0] > 0)
- {
- ::TESetText(inString + 1, inString[0], mBulletTextEditH);
- SetTextToBullets(mBulletTextEditH);
- }
-
-
- // Align the TextEdit records and select the text, if any
- AlignTextEditRects();
- SelectAll();
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::LPasswordField
- //-----------------------------------------------------------------------------
- // Construct from the data in a stream.
- //-----------------------------------------------------------------------------
- LPasswordField::LPasswordField(LStream *inStream) : LEditField(inStream)
- { Uint8 attributes = 0;
-
-
-
- // The LEditField constructor has built itself from the data in
- // inStream, but didn't save the attributes away anywhere. We
- // have to recreate the attributes ourselves by hand.
- if (mHasBox)
- attributes |= editAttr_Box;
-
- if (mHasWordWrap)
- attributes |= editAttr_WordWrap;
-
- if (TEFeatureFlag(teFAutoScr, teBitTest, mTextEditH) == teBitSet)
- attributes |= editAttr_AutoScroll;
-
- if (TEFeatureFlag(teFTextBuffering, teBitTest, mTextEditH) == teBitSet)
- attributes |= editAttr_TextBuffer;
-
- if (TEFeatureFlag(teFOutlineHilite, teBitTest, mTextEditH) == teBitSet)
- attributes |= editAttr_OutlineHilite;
-
- if (TEFeatureFlag(teFInlineInput, teBitTest, mTextEditH) == teBitSet)
- attributes |= editAttr_InlineInput;
-
- if (TEFeatureFlag(teFUseTextServices, teBitTest, mTextEditH) == teBitSet)
- attributes |= editAttr_TextServices;
-
-
-
- // Initialise ourselves from these attributes
- InitPassField(attributes);
-
-
- // Set the visible TextEdit record to match the hidden one
- SetVisibleFromHidden();
-
-
- // Align the TextEdit records and select the text, if any
- AlignTextEditRects();
- SelectAll();
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::InitPassField
- //-----------------------------------------------------------------------------
- // Initialise the member variables of a PassField.
- //
- // We also fudge some of the things our parent (LEditField) set up
- // earlier.
- //-----------------------------------------------------------------------------
- void LPasswordField::InitPassField(Uint8 inAttributes)
- { Rect viewRect = {0, 0, 0, 0};
-
-
-
- // The LEditField constructor will have build our mTextEditH member.
- // We move it somewhere off screen so it won't be visible.
- OffsetRect(&(*mTextEditH)->viewRect, kHiddenTEOffset, kHiddenTEOffset);
-
-
- // Set the focus to be ourselves, rather than the EditField
- StFocusAndClipIfHidden focus(this);
-
-
-
- // Initialise our internal variables
- mBulletTextEditH = ::TENew(&viewRect, &viewRect);
- mBullet = '•';
-
-
-
- // Set the optional features for the TextEdit field
- ::TEFeatureFlag(teFAutoScr,
- ((inAttributes & editAttr_AutoScroll) != 0) ?
- teBitSet : teBitClear, mBulletTextEditH);
-
- ::TEFeatureFlag(teFTextBuffering,
- ((inAttributes & editAttr_TextBuffer) != 0) ?
- teBitSet : teBitClear, mBulletTextEditH);
-
- ::TEFeatureFlag(teFOutlineHilite,
- ((inAttributes & editAttr_OutlineHilite) != 0) ?
- teBitSet : teBitClear, mBulletTextEditH);
-
- ::TEFeatureFlag(teFInlineInput,
- ((inAttributes & editAttr_InlineInput) != 0) ?
- teBitSet : teBitClear, mBulletTextEditH);
-
- ::TEFeatureFlag(teFUseTextServices,
- ((inAttributes & editAttr_TextServices) != 0) ?
- teBitSet : teBitClear, mBulletTextEditH);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::~LPasswordField
- //-----------------------------------------------------------------------------
- // Destructor
- //-----------------------------------------------------------------------------
- LPasswordField::~LPasswordField()
- {
- if (mBulletTextEditH != nil)
- ::TEDispose(mBulletTextEditH);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::SetDescriptor
- //-----------------------------------------------------------------------------
- // Set the contents of a PasswordField from a Pascal string.
- //
- // We call our parent class to set the text of the offscreen item
- // correctly, then resynch the visible field.
- //-----------------------------------------------------------------------------
- void LPasswordField::SetDescriptor(ConstStr255Param inDescriptor)
- {
-
- // Call our parent class
- LEditField::SetDescriptor(inDescriptor);
-
-
- // Resynch the visible field, and redraw
- SetVisibleFromHidden();
- Refresh();
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::SetBullet
- //-----------------------------------------------------------------------------
- // Set the bullet character to be used.
- //-----------------------------------------------------------------------------
- void LPasswordField::SetBullet(Int16 inBullet)
- {
- mBullet = inBullet;
- Refresh();
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::SetTextTraitsID
- //-----------------------------------------------------------------------------
- // Set the text traits of the PasswordField.
- //-----------------------------------------------------------------------------
- void LPasswordField::SetTextTraitsID(ResIDT inTextTraitsID)
- {
- // Call our parent class for the off screen TextEdit record
- LEditField::SetTextTraitsID(inTextTraitsID);
-
- // Set the visible TextEdit record
- UTextTraits::SetTETextTraits(mTextTraitsID, mBulletTextEditH);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::DrawSelf
- //-----------------------------------------------------------------------------
- // Draw a PasswordField.
- //-----------------------------------------------------------------------------
- void LPasswordField::DrawSelf()
- { Rect frame;
-
-
- // Calculate the local frame rectangle
- CalcLocalFrameRect(frame);
-
-
- // Draw a border if necessary
- if (mHasBox)
- {
- DrawBox();
- ::InsetRect(&frame, 2, 2);
- }
-
-
- // A Mac TERec stores a pointer to its owner port We have to
- // change it to the current port in case we are drawing into
- // a port that is not the owner port. This happens when we are
- // printing or drawing into an offscreen port.
- GrafPtr savePort = (**mBulletTextEditH).inPort;
- (**mBulletTextEditH).inPort = UQDGlobals::GetCurrentPort();
-
- ::TEUpdate(&frame, mBulletTextEditH);
-
- (**mBulletTextEditH).inPort = savePort;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::ClickSelf
- //-----------------------------------------------------------------------------
- // Respond to clicks inside a PasswordField.
- //-----------------------------------------------------------------------------
- void LPasswordField::ClickSelf(const SMouseDownEvent &inMouseDown)
- {
-
- // If we're not the target, then clicking in us makes us
- // the target. Since TEClick will set a new selection
- // ragen, we clear the current selection range to avoid
- // an ugly flash.
- if (!IsTarget())
- {
- ::TESetSelect(0, 0, mTextEditH);
- ::TESetSelect(0, 0, mBulletTextEditH);
- SwitchTarget(this);
- }
-
-
- // If we're the target, handle the click with TextEdit
- if (IsTarget())
- {
- FocusDraw();
- AdjustTextWidth(true);
- ::TEClick(inMouseDown.whereLocal,
- ((inMouseDown.macEvent.modifiers & shiftKey) != 0),
- mBulletTextEditH);
-
-
- // Since TEClick holds on to the mouse until the user lets go,
- // we need to manually match up the selection of the hidden
- // TextEdit record to that of the visible one.
- (*mTextEditH)->selStart = (*mBulletTextEditH)->selStart;
- (*mTextEditH)->selEnd = (*mBulletTextEditH)->selEnd;
- AdjustTextWidth(false);
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::ObeyCommand
- //-----------------------------------------------------------------------------
- // Handle standard editing commands.
- //-----------------------------------------------------------------------------
- Boolean LPasswordField::ObeyCommand(CommandT inCommand, void *ioParam)
- { Boolean cmdHandled = true;
- Int32 offset;
-
-
-
- // Case out on the command
- switch (inCommand) {
- case cmd_Cut:
- ::TECut(mTextEditH);
- PostAction(new LTECutAction(mBulletTextEditH, this, this));
- break;
-
-
- case cmd_Copy:
- ::TECopy(mBulletTextEditH);
- ::ZeroScrap();
- ::TEToScrap();
- break;
-
-
- case cmd_Paste:
- // If pasting would exceed the maximum field size, we beep
- if (TooManyCharacters(::GetScrap(nil, 'TEXT', &offset)))
- ::SysBeep(30);
-
-
- // Otherwise, past it in to both records. We need to move
- // the visible TextEdit record off screen while pasting,
- // since we need to munge the characters to bullets after
- // they've been pasted in.
- else
- {
- // Paste it into the off screen record
- PostAction(new LTEPasteAction(mTextEditH, this, this));
-
- // Move the visible text record off the screen
- OffsetRect(&(*mBulletTextEditH)->viewRect, 5000, 5000);
-
- // Paste in the text, and convert it to bullets
- PostAction(new LTEPasteAction(mBulletTextEditH, this, this));
- SetTextToBullets(mBulletTextEditH);
-
- // Move the visible text record back onto the screen and redraw
- OffsetRect(&(*mBulletTextEditH)->viewRect, -5000, -5000);
- AlignTextEditRects();
- Refresh();
- }
- break;
-
-
- case cmd_Clear:
- ::TEDelete(mTextEditH);
- PostAction(new LTEClearAction(mBulletTextEditH, this, this));
- break;
-
-
- default:
- // Our parent is an LEditField, not an LCommander
- cmdHandled = LEditField::ObeyCommand(inCommand, ioParam);
- break;
- }
-
-
- // Return as the command was handled or not
- return cmdHandled;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::FindCommandStatus
- //-----------------------------------------------------------------------------
- // Pass back the status of a command.
- //
- // We don't *really* need to override this, since all of our commands
- // are tied to the current selection (which should be the same in
- // both the visible and off screen TextEdit records).
- //
- // But, we override just to make sure we can get the behaviour we want.
- //-----------------------------------------------------------------------------
- void LPasswordField::FindCommandStatus(CommandT inCommand,
- Boolean &outEnabled,
- Boolean &outUsesMark,
- Char16 &outMark,
- Str255 outName)
- {
-
-
- // Case out on the command
- switch (inCommand) {
- case cmd_Cut:
- case cmd_Copy:
- case cmd_Clear:
- // Cut, copy, and clear are enabled if something is selected
- outEnabled = ((**mBulletTextEditH).selStart != (**mBulletTextEditH).selEnd);
- break;
-
-
- case cmd_SelectAll:
- // We can only select everything if there's something to select
- outEnabled = (**mBulletTextEditH).teLength > 0;
- break;
-
-
- default:
- // Pass it to the LEditField if it's anything else
- LEditField::FindCommandStatus(inCommand, outEnabled, outUsesMark, outMark, outName);
- break;
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::HandleKeyPress
- //-----------------------------------------------------------------------------
- // Handle a key stroke directed at a PasswordField.
- //
- // We return true if we handle the keystroke.
- //-----------------------------------------------------------------------------
- Boolean LPasswordField::HandleKeyPress(const EventRecord &inKeyEvent)
- { Boolean keyHandled = true;
- EKeyStatus theKeyStatus = keyStatus_Input;
- Int16 theKey = inKeyEvent.message & charCodeMask;
-
-
-
- // We always pass it up when the command key is down
- if (inKeyEvent.modifiers & cmdKey)
- theKeyStatus = keyStatus_PassUp;
- else if (mKeyFilter != nil)
- theKeyStatus = (*mKeyFilter)(inKeyEvent);
-
-
-
- // Case out on theKeyStatus
- switch (theKeyStatus) {
- case keyStatus_Input:
- // Check to see if we're at the character limit.
- // This is NOT compatible with two-byte character systems
- if (TooManyCharacters(1))
- {
- SysBeep(30);
- break;
- }
-
- // Otherwise, put the keystroke into the real TextEdit record
- TEKey(theKey, mTextEditH);
-
- // Turn the key into a bullet
- theKey = mBullet;
-
- // Put the bullet character into the visible TextEdit record
- if (mTypingAction == nil)
- {
- mTypingAction = new LTETypingAction(mBulletTextEditH, this, this);
- PostAction(mTypingAction);
- }
- if (mTypingAction != nil)
- mTypingAction->InputCharacter(theKey);
- else
- ::TEKey(theKey, mBulletTextEditH);
- UserChangedText();
- break;
-
-
- case keyStatus_TEDelete: {
- if ((**mBulletTextEditH).selEnd > 0)
- {
- // Do it to the hidden text edit field
- ::TEKey(char_Backspace, mTextEditH);
-
- // Do it to the visible text edit field
- if (mTypingAction == nil)
- {
- mTypingAction = new LTETypingAction(mBulletTextEditH, this, this);
- PostAction(mTypingAction);
- }
- if (mTypingAction != nil)
- mTypingAction->BackwardErase();
- else
- ::TEKey(char_Backspace, mBulletTextEditH);
- UserChangedText();
- }
- break; }
-
-
- case keyStatus_TECursor: {
- StFocusAndClipIfHidden teCursorFocus(this);
- ::TEKey(theKey, mTextEditH);
- ::TEKey(theKey, mBulletTextEditH);
- break; }
-
-
- case keyStatus_ExtraEdit: {
- StFocusAndClipIfHidden extraEditFocus(this);
- switch (theKey) {
- case char_Home:
- ::TESetSelect(0, 0, mTextEditH);
- ::TESetSelect(0, 0, mBulletTextEditH);
- break;
-
-
- case char_End:
- ::TESetSelect(max_Int16, max_Int16, mTextEditH);
- ::TESetSelect(max_Int16, max_Int16, mBulletTextEditH);
- break;
-
-
- case char_FwdDelete:
- if ((**mBulletTextEditH).selStart < (**mBulletTextEditH).teLength)
- {
- // Do it to the hidden record
- if ((**mTextEditH).selStart == (**mTextEditH).selEnd)
- ::TESetSelect((**mTextEditH).selStart,
- (**mTextEditH).selStart + 1,
- mTextEditH);
- ::TEDelete(mTextEditH);
-
-
- // Do it to the visible record
- if (mTypingAction == nil)
- {
- mTypingAction = new LTETypingAction(mBulletTextEditH, this, this);
- PostAction(mTypingAction);
- }
- if (mTypingAction != nil)
- mTypingAction->ForwardErase();
- else
- if ((**mBulletTextEditH).selStart == (**mBulletTextEditH).selEnd)
- ::TESetSelect((**mBulletTextEditH).selStart,
- (**mBulletTextEditH).selStart + 1,
- mTextEditH);
- ::TEDelete(mTextEditH);
- UserChangedText();
- }
- break;
-
-
- default:
- keyHandled = LEditField::HandleKeyPress(inKeyEvent);
- break;
- }
- break; }
-
-
- case keyStatus_Reject:
- // Can do something with rejected keystrokes here
- SysBeep(30);
- break;
-
-
- case keyStatus_PassUp:
- keyHandled = LEditField::HandleKeyPress(inKeyEvent);
- break;
- }
-
-
-
- // Return as the keystroke was handled or not
- return(keyHandled);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::SelectAll
- //-----------------------------------------------------------------------------
- // Select the entire contents of a PasswordField.
- //-----------------------------------------------------------------------------
- void LPasswordField::SelectAll()
- {
-
- // Call our parent class
- LEditField::SelectAll();
-
-
- // Select the visible TextEdit record
- StFocusAndClipIfHidden focus(this);
- ::TESetSelect(0, max_Int16, mBulletTextEditH);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::AlignTextEditRects
- //-----------------------------------------------------------------------------
- // Align the view and destination rectangles of the Toolbox TextEdit
- // records with the Frame of a PasswordField.
- //-----------------------------------------------------------------------------
- void LPasswordField::AlignTextEditRects()
- { Rect textFrame;
-
-
-
- // If the Frame is outside QuickDraw space, we put textFrame at
- // the upper left limit of QuickDraw space (extreme negative
- // coordinates). That location is gauranteed to be offscreen
- // (unless you have a control longer than 32K pixels). since
- // PowerPlant Image coordinates start at (0, 0) and are never
- // negative.
- if (!CalcLocalFrameRect(textFrame))
- {
- textFrame.left = min_Int16;
- textFrame.right = textFrame.left + mFrameSize.width;
- textFrame.top = min_Int16;
- textFrame.bottom = textFrame.top + mFrameSize.height;
- }
-
-
- // If we have a box, move in past it
- if (mHasBox)
- ::InsetRect(&textFrame, 2, 2);
-
-
- // Set the TextEdit view and destination rectangles to be the
- // same as the Frame. We do *not* set the viewRect of the
- // mTextEditH TextEdit record, since that's what's keeping it
- // off screen and out of the way.
- // (**mTextEditH).viewRect = textFrame;
- (**mTextEditH).destRect = textFrame;
- (**mBulletTextEditH).viewRect = textFrame;
- (**mBulletTextEditH).destRect = textFrame;
- AdjustTextWidth(false);
-
-
- // Let TextEdit adjust the line breaks
- ::TECalText(mTextEditH);
- ::TECalText(mBulletTextEditH);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::AdjustTextWidth
- //-----------------------------------------------------------------------------
- // Adjust the width of the destination rectangle of the Toolbox TextEdit
- // record
- //
- // This function does nothing if WordWrap is ON. If WordWrap is OFF, this
- // function sets the width of the TextEdit destination rectangle to either
- // the width of the text or a very large number, depending on the value
- // of inShrinkToText.
- //
- // This adjustment is needed to make autoscrolling work properly when
- // WordWrap is off. While entering text, the destination rectangle should
- // be very wide so that the text doesn't word wrap. However, while
- // clicking, it should be just as wide as the text so that the PassField
- // does not autoscroll past the edge of the text.
- //-----------------------------------------------------------------------------
- void LPasswordField::AdjustTextWidth(Boolean inShrinkToText)
- { Rect textFrame;
- Int16 destWidth = 4000; // Very Large Number
- Int16 just;
-
-
-
- // We adjust only of WordWrap is OFF
- if (!mHasWordWrap)
- {
- // Get the size of the editable text area, taking into account a box
- CalcLocalFrameRect(textFrame);
- if (mHasBox)
- ::InsetRect(&textFrame, 2, 2);
-
-
-
- // Calculate the width of the text in the PasswordField
- if (inShrinkToText)
- {
- Point startPoint = ::TEGetPoint(0, mBulletTextEditH);
- Point endPoint = ::TEGetPoint((**mBulletTextEditH).teLength, mBulletTextEditH);
- destWidth = endPoint.h - startPoint.h;
-
- if (destWidth < textFrame.right - textFrame.left)
- destWidth = textFrame.right - textFrame.left;
- }
-
- // Direction to extend dest rect depends on the text justification
- just = (**mBulletTextEditH).just;
- if (just == teFlushDefault)
- {
- // For left justificaton, GetSysDirection returns teFlushDefault.
- // For right, it returns teFlushRight
- just = ::GetSysDirection();
- }
-
-
- // Case out on the justification
- switch ((**mBulletTextEditH).just) {
- case teFlushLeft:
- case teFlushDefault:
- // Text fixed on left and grows right
- (**mBulletTextEditH).destRect.right = (**mBulletTextEditH).destRect.left + destWidth;
- break;
-
-
- case teFlushRight:
- // Text grows to the left
- (**mBulletTextEditH).destRect.left = (**mBulletTextEditH).destRect.right - destWidth;
- break;
-
-
- case teCenter:
- // Text grows left and right
- Int16 center = (textFrame.left + textFrame.right) / 2;
- (**mBulletTextEditH).destRect.left = center - 2000;
- (**mBulletTextEditH).destRect.right = center + 2000;
- break;
- }
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::BeTarget
- //-----------------------------------------------------------------------------
- // A PasswordField is becoming the target.
- //-----------------------------------------------------------------------------
- void LPasswordField::BeTarget()
- {
- // Call our parent class
- LEditField::BeTarget();
-
-
- // Show the active selection
- ::TEActivate(mBulletTextEditH);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::DontBeTarget
- //-----------------------------------------------------------------------------
- // PasswordField is no longet the target.
- //
- // Our parent removes the PasswordField from the IdleQueue.
- //-----------------------------------------------------------------------------
- void LPasswordField::DontBeTarget()
- {
-
- // Call our parent class
- LEditField::DontBeTarget();
-
-
- // Show the inactive selection
- ::TEDeactivate(mBulletTextEditH);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::SpendTime
- //-----------------------------------------------------------------------------
- // At idle time, we flash the insertion cursor if necessary.
- //-----------------------------------------------------------------------------
- void LPasswordField::SpendTime(const EventRecord &inMacEvent)
- {
-
- // Flash the cursor
- if (FocusExposed())
- ::TEIdle(mBulletTextEditH);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::SavePlace
- //-----------------------------------------------------------------------------
- // Save the TextEdit rectangles.
- //-----------------------------------------------------------------------------
- void LPasswordField::SavePlace(LStream *outPlace)
- {
- LPane::SavePlace(outPlace);
-
- Rect viewRect = (**mBulletTextEditH).viewRect;
- outPlace->WriteData(&viewRect, sizeof(Rect));
-
- Rect destRect = (**mBulletTextEditH).destRect;
- outPlace->WriteData(&destRect, sizeof(Rect));
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::RestorePlace
- //-----------------------------------------------------------------------------
- // Restore the TextEdit rectangles.
- //-----------------------------------------------------------------------------
- void LPasswordField::RestorePlace(LStream *inPlace)
- {
- LPane::RestorePlace(inPlace);
-
- Rect viewRect;
- inPlace->ReadData(&viewRect, sizeof(Rect));
- (**mBulletTextEditH).viewRect = viewRect;
-
- Rect destRect;
- inPlace->ReadData(&destRect, sizeof(Rect));
- (**mBulletTextEditH).destRect = destRect;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::SetTextToBullets
- //-----------------------------------------------------------------------------
- // Set every character in a TextEdit record to be the bullet character.
- //-----------------------------------------------------------------------------
- void LPasswordField::SetTextToBullets(TEHandle theTextHnd)
- { char *theChar;
- short i, theLen;
-
-
- // Get the text, and it's length
- theChar = *(::TEGetText(theTextHnd));
- theLen = (*theTextHnd)->teLength;
-
-
- // If there's no text, we're done
- if (theLen == 0)
- return;
-
-
- // Set every character to the bullet character
- for (i = 0; i < theLen; i++)
- *theChar++ = mBullet;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- //=============================================================================
- // LPasswordField::SetVisibleFromHidden
- //-----------------------------------------------------------------------------
- // Set every character in mBulletTextEditH to be a bullet character,
- // adjusting it's length to match mTextEditH if needs be.
- //
- // mBulletTextEditH is *not* redrawn - call Refresh() after calling this
- // routine.
- //-----------------------------------------------------------------------------
- void LPasswordField::SetVisibleFromHidden(void)
- { CharsHandle theHnd;
- char *theChar;
- short i, theLen;
-
-
-
- // Find out how much text is in the off screen TextEdit record
- theHnd = ::TEGetText(mTextEditH);
- ::HLock(theHnd);
- theChar = *theHnd;
- theLen = (*mTextEditH)->teLength;
-
-
- // Set the text of the on screen TextEdit record to match the offscreen
- ::TESetText(theChar, theLen, mBulletTextEditH);
-
-
- // Unclock the text handle of the off screen TextEdit record
- ::HUnlock(theHnd);
-
-
- // Convert the text of the on screen record to bullets
- SetTextToBullets(mBulletTextEditH);
- }
-